home *** CD-ROM | disk | FTP | other *** search
- /*
- File: SimpleAppLauncher.c
- */
-
- #include <Types.h>
- #include <Memory.h>
- #include <LowMem.h>
- #include <Quickdraw.h>
- #include <Files.h>
- #include <Resources.h>
- #include <TextUtils.h>
- #include <TextEdit.h>
- #include <MixedMode.h>
- #include <Events.h>
- #include <Processes.h>
- #include <Gestalt.h>
- #include <Printing.h>
- #include <ToolUtils.h>
- #include <assert.h>
-
- #include "SimpleAppLauncher.h"
-
- // PROTOTYPES
-
- static Boolean HandleEventForPluginModule(EventRecord *inEvent);
- static void TerminatePluginModule(void);
- static ShellErr HandleMouseDownInUtilsPanel(EventRecord *inEvent, Boolean *wasHandled);
- static ShellErr HandleMouseDownInSALPanel(EventRecord *inEvent, Boolean *wasHandled);
- static Boolean HandleMouseDownInHelpPanel(EventRecord *inEvent);
- static Boolean QuitProcess(ProcessSerialNumber *inApplicationPSN);
- static OSErr SetupSALPanel( SInt16 inPrefRsrcID);
- static OSErr SetupHelpPanel(void);
- static Boolean ShouldDrawColor(void);
- static void SendQuitEventToApplication(void);
- static ShellErr SetUpAppleEventHandlers();
- static ShellErr RemoveAppleEventHandlers();
- pascal OSErr ChildDiedHandler(const AppleEvent *inAppleEvent, const AppleEvent */* outReply */, SInt32 /* inRefcon */ );
-
- // GLOBALS
-
- DialogPtr gSALPanel = NULL;
- DialogPtr gHelpPanel = NULL;
- Boolean gHelpPanelOpen = false;
- Boolean gApplicationLaunched = false;
- ProcessSerialNumber gApplicationPSN;
- AEEventHandlerUPP gChildDiedHandlerUPP = NULL;
- Boolean gQuitApponExit = true; //Set this to true if you want the application to quit when leaving the plugin.
- SInt16 gPrefID;
- Boolean gIsLaunchCheckBoxShowing = false;
-
- //--------------------------------------------------------------------------------
- // InitializePluginModule
- //--------------------------------------------------------------------------------
-
- void InitializePluginModule(void *inPSTable, SInt32 inRefCon, Boolean inEnterAtBeginning)
- {
- #pragma unused (inRefCon,inEnterAtBeginning)
- ShellErr err;
- SInt16 refNum = -1;
-
- EnterPlugin();
- SetupPlugin(inPSTable);
-
- // Register our event handler routine
- err = PSRegisterHandler(kEventHandlerID, (UniversalProcPtr)HandleEventForPluginModule);
-
- if (err == noErr)
- {
- // Resister our termination handler routine
- err = PSRegisterHandler(kTerminationHandlerID, (UniversalProcPtr)TerminatePluginModule);
-
- if (err == noErr)
- {
- //Register ChildDied event handler
- err = SetUpAppleEventHandlers();
-
- if (err == noErr)
- {
- err = PSSetupNewPanel(kSALPanelRsrcID, &gSALPanel);
- if (err == noErr)
- {
- err = SetupSALPanel( LoWord( inRefCon ) );
- if (err == noErr)
- PSShowPanel(gSALPanel);
- }
- }
- }
- }
-
- if (err != noErr)
- {
- PSErrorAlert(err, true, "\p", "\p", "\p", "\p", kQuitButtonIndex, kContinueNotQuitBtnIndex);
- PSQuitShell(kDontAllowUserToContinue);
- }
-
- ExitPlugin();
- }
-
- //--------------------------------------------------------------------------------
- // TerminatePluginModule
- //--------------------------------------------------------------------------------
-
- static void TerminatePluginModule()
- {
- PanelItemType itemType;
- Handle itemHandle;
- Rect itemRect;
-
- EnterPlugin();
-
- // Save launch checkbox state, if checkbox is showing
- if( gIsLaunchCheckBoxShowing && PSGetPanelItem(gSALPanel, kLaunchCheckBox, &itemType, &itemHandle, &itemRect) == noErr )
- {
- Boolean savedCheckboxState = GetControlValue( (ControlHandle)itemHandle ) != 0;
-
- PSSetGlobalData( 'lacb', ( GlobalDataPtr ) &savedCheckboxState, sizeof(Boolean) );
- }
-
-
- if (gQuitApponExit)
- {
- if (gApplicationLaunched)
- SendQuitEventToApplication();
- }
-
- RemoveAppleEventHandlers();
-
- ExitPlugin();
- }
-
- //--------------------------------------------------------------------------------
- // HandleEventForPluginModule
- //--------------------------------------------------------------------------------
-
- static Boolean HandleEventForPluginModule(EventRecord *inEvent)
- {
- ShellErr err = noErr;
- Boolean wasHandled = false;
-
- EnterPlugin();
-
- switch (inEvent->what)
- {
-
- case mouseDown:
- if (FrontWindow() == gSALPanel)
- err = HandleMouseDownInSALPanel(inEvent, &wasHandled);
- else if (FrontWindow() == gHelpPanel) // check for Help panel
- wasHandled = PSHandleHelpWindowEvent(gHelpPanel, inEvent);
- break;
-
- case osEvt: // Resume events only!
- if (((UInt32)inEvent->message >> 24) == suspendResumeMessage)
- {
- if ((inEvent->message & resumeFlag) != 0)
- (void) PSHandleHelpWindowEvent(gHelpPanel, inEvent);
- }
- break;
-
- case kHighLevelEvent:
- AEProcessAppleEvent(inEvent);
-
- wasHandled = true;
- break;
-
- default:
- break;
- }
-
- ExitPlugin();
-
- return(wasHandled);
- }
-
- //--------------------------------------------------------------------------------
- // HandleMouseDownInSALPanel
- //--------------------------------------------------------------------------------
-
- static ShellErr HandleMouseDownInSALPanel(EventRecord *inEvent, Boolean *wasHandled)
- {
- ShellErr err = noErr;
- SALPrefsHandle prefsHandle;
- SInt16 itemHit;
- Boolean launchedOK;
- AEDesc optionalParameters;
- PanelItemType itemType;
- Handle itemHandle;
- Rect itemRect;
-
- prefsHandle = (SALPrefsHandle) GetResource(kSALPrefsResType, gPrefID); // Just get the first one
-
- *wasHandled = false;
-
- if (PSGetPanelItemHit(gSALPanel, inEvent, &itemHit))
- {
- switch (itemHit)
- {
-
- case kContinueButton:
- if (prefsHandle != NULL && (**prefsHandle).format == 3 )
- {
- if( gIsLaunchCheckBoxShowing && PSGetPanelItem(gSALPanel, kLaunchCheckBox, &itemType, &itemHandle, &itemRect) == noErr && GetControlValue( (ControlHandle)itemHandle ) == 0 )
- {
- PSGoToNextPlugin(kUseDefaultNextModuleName);
- *wasHandled = true;
- break;
- }
-
- if (gApplicationLaunched)
- { // If application has been launched
- SetFrontProcess(&gApplicationPSN);
- }
- else
- {
- // Launch Application
- optionalParameters.descriptorType = 'NULL';
- optionalParameters.dataHandle = NULL;
- launchedOK = PSLaunchFile((**prefsHandle).applicationflrfID, (**prefsHandle).documentflrfID, &optionalParameters, true, &gApplicationPSN);
- if (launchedOK)
- gApplicationLaunched = true;
-
- *wasHandled = true;
- }
- }
- else
- err = kNoPrefsErr;
- break;
-
- case kLaunchCheckBox:
- if( PSGetPanelItem(gSALPanel, kLaunchCheckBox, &itemType, &itemHandle, &itemRect) == noErr )
- SetControlValue( (ControlHandle)itemHandle, ! GetControlValue( (ControlHandle)itemHandle ) );
- break;
-
- case kHelpButton:
- DisplayHelp();
- *wasHandled = true;
- break;
-
- default:
- break;
- }
- }
- return(err);
- }
-
-
- //--------------------------------------------------------------------------------
- // DisplayHelp
- //--------------------------------------------------------------------------------
-
- void DisplayHelp()
- {
- ShellErr err = noErr;
-
- if (gHelpPanelOpen) // Is it already open ?
- {
- err = PSShowPanel(gHelpPanel);
- }
- else
- {
- PSDisplayHelpWindow(gHelpPanel);
- gHelpPanelOpen = true;
- }
-
- if (err != noErr)
- {
- PSErrorAlert(err, true, "\p", "\p", "\p", "\p", kQuitButtonIndex, kContinueNotQuitBtnIndex);
- PSQuitShell(kDontAllowUserToContinue);
- }
- }
-
-
- //--------------------------------------------------------------------------------
- // SetupSALPanel
- //
- // Sets up the various user items in the panel to their correct type, specifiying
- // the data found in the SAL preference resource which is read from the ClientData
- // file.
- // This routine should be called after PSSetupNewPanel() but before PSShowPanel() for
- // the SAL panel.
- //
- // Parameters
- //
- // Returns
- //--------------------------------------------------------------------------------
-
- static OSErr SetupSALPanel( SInt16 inPrefRsrcID )
- {
- SALPrefsHandle prefsHandle;
- SALPrefsPtr prefsPtr;
- OSErr err = noErr;
-
- if( inPrefRsrcID == 0 ) {
- SInt16** theIDHandle = (SInt16**) GetResource( kResIDResType, 128 ); // Get Resource ID for plugin preference
- if (theIDHandle != NULL)
- gPrefID = **theIDHandle;
- else
- gPrefID = 3500;
- }
- else
- gPrefID = inPrefRsrcID;
-
- prefsHandle = (SALPrefsHandle) GetResource(kSALPrefsResType, gPrefID); // Get Resource Preference
-
- if (prefsHandle != NULL)
- {
- if ((**prefsHandle).format == 3)
- {
- TEHandle text;
- SInt16 fontNum, fontStyle, fontSize;
- PanelItemType itemType;
- Handle itemHandle;
- Handle docHandle;
- Rect itemRect;
- PicHandle picHandle = NULL;
-
- HLock((Handle)prefsHandle);
- prefsPtr = *prefsHandle;
-
- // Setup the panel title string.
- err = PSGetPanelItem(gSALPanel, kTitleTextItem, &itemType, &itemHandle, &itemRect);
- if (err == noErr)
- {
- if (PSReadFontInfo(kFontInfoInShell, kUpgraderFonts, kLargeTextStyle, &fontNum, &fontStyle, &fontSize))
- {
- text = PSNewStyledStringItem(&itemRect, prefsPtr->SALSTRListRsrsID, 1, fontNum, fontStyle, fontSize);
- if (text != NULL)
- err = PSSetPanelItem(gSALPanel, kTitleTextItem, kStyledStringType, (Handle)text, &itemRect);
- else
- err = kCannotLoadNeededResourceErr;
- }
- }
-
- if (err == noErr)
- {
- // Setup the SAL panel main text.
- if (prefsPtr->mainTextReferenceID != 0) // Ignore id 0 if the Client does not want any text
- {
- err = PSGetPanelItem(gSALPanel, kInstallStepsTextItem, &itemType, &itemHandle, &itemRect);
- if (err == noErr)
- {
- if ((prefsPtr->flags & kMainTextInFile) == kMainTextInFile)
- {
- docHandle = PSNewDocViewerItem(gSALPanel, &itemRect, kDocFileType, prefsPtr->mainTextReferenceID, 0);
- if (docHandle != NULL)
- err = PSSetPanelItem(gSALPanel, kInstallStepsTextItem, kDocFileType, (Handle)docHandle, &itemRect);
- else
- err = kCannotLoadNeededResourceErr;
- }
- else
- {
- text = PSNewStyledTextItem(&itemRect, prefsPtr->mainTextReferenceID);
- if (text != NULL)
- err = PSSetPanelItem(gSALPanel, kInstallStepsTextItem, kStyledTextType, (Handle)text, &itemRect);
- else
- err = kCannotLoadNeededResourceErr;
- }
- }
- }
-
- // Setup the background PICT item
- if (prefsPtr->backgroundPICTResID != 0) // Ignore id 0 if the Client does not want any background PICT
- {
- if (err == noErr)
- {
-
- // Get color first
- if (ShouldDrawColor())
- picHandle = GetPicture(prefsPtr->backgroundPICTResID);
- else
- picHandle = GetPicture(prefsPtr->backgroundPICTResID + 1);
-
- if (picHandle == NULL)
- picHandle = GetPicture(prefsPtr->backgroundPICTResID);
-
- if (picHandle != NULL)
- {
- err = PSGetPanelItem(gSALPanel, kBackgroundPICTitem, &itemType, &itemHandle, &itemRect);
- if (err == noErr)
- err = PSSetPanelItem(gSALPanel, kBackgroundPICTitem, kPICTType, (Handle)picHandle, &itemRect);
- }
- else
- {
- err = kCannotLoadNeededResourceErr;
- }
- }
- }
-
- if( PSGetPanelItem(gSALPanel, kLaunchCheckBox, &itemType, &itemHandle, &itemRect) == noErr )
- {
-
- // Hide/show the launch checkbox
- if ( prefsPtr->flags & kShowLaunchCheckbox )
- {
- Str255 checkBoxNameStr;
- Boolean savedCheckboxState;
- SInt32 actualSize;
-
- gIsLaunchCheckBoxShowing = true;
- ShowControl( (ControlHandle)itemHandle );
-
- // Set checkbox title
- GetIndString( checkBoxNameStr, prefsPtr->SALSTRListRsrsID, 3 );
- SetControlTitle( (ControlHandle)itemHandle, checkBoxNameStr );
-
- // Set launch checkbox default state
- if ( prefsPtr->flags & kPrecheckLaunchCheckbox)
- SetControlValue( (ControlHandle)itemHandle, 1 );
- else
- SetControlValue( (ControlHandle)itemHandle, 0 );
-
- // Override default checkbox state if we've saved the state using global data
- if( PSGetGlobalData( 'lacb', ( GlobalDataPtr ) &savedCheckboxState, sizeof(Boolean), &actualSize ) == noErr )
- {
- if ( savedCheckboxState)
- SetControlValue( (ControlHandle)itemHandle, 1 );
- else
- SetControlValue( (ControlHandle)itemHandle, 0 );
- }
-
- }
- else
- {
- gIsLaunchCheckBoxShowing = false;
- HideControl( (ControlHandle)itemHandle );
- }
-
-
- }
-
- // Find out if Application should be left open when exiting plugin
- if ((prefsPtr->flags & kKeepApplicationOpen) == kKeepApplicationOpen)
- gQuitApponExit = false;
- }
- HUnlock((Handle)prefsHandle);
- }
- else
- {
- err = kUnsupportedPrefsFormatErr;
- }
- }
- else
- {
- err = kNoPrefsErr;
- }
-
- PSSetPanelItemAction(gSALPanel, kContinueButton, kDefaultButtonMask);
- PSSetPanelItemAction(gSALPanel, kGoBackButton, kGoBackButtonMask);
-
- if (err == noErr)
- err = SetupHelpPanel();
-
- return(err);
- }
-
- //--------------------------------------------------------------------------------
- // SetupHelpPanel
- //
- // Sets up the various user items in the panel to their correct type, specifiying
- // the data found in the SAL preference resource which is read from the ClientData
- // file.
- // This routine should be called after PSSetupNewPanel() but before PSShowPanel() for
- // the Help panel.
- //
- // Parameters
- //
- // Returns
- //--------------------------------------------------------------------------------
-
- static OSErr SetupHelpPanel()
- {
- SALPrefsHandle prefsHandle;
- SALPrefsPtr prefsPtr;
- OSErr err = noErr;
-
- prefsHandle = (SALPrefsHandle) GetResource(kSALPrefsResType, gPrefID); // Just get the first one
-
- if (prefsHandle != NULL)
- {
- if ((**prefsHandle).format == 3)
- {
- Str255 helpPanelTitle;
-
- HLock((Handle)prefsHandle);
- prefsPtr = *prefsHandle;
-
- if ((prefsPtr->flags & kHelpTextInFile) == kHelpTextInFile)
- {
- GetIndString(helpPanelTitle, prefsPtr->SALSTRListRsrsID, 2);
- err = PSSetupHelpWindow(kReadFromSimpleTextFile, prefsPtr->helpTextReferenceID, prefsPtr->basePICTResID, helpPanelTitle, &gHelpPanel);
- }
- else
- {
- GetIndString(helpPanelTitle, prefsPtr->SALSTRListRsrsID, 2);
- err = PSSetupHelpWindow(kReadFromResourceFile, prefsPtr->helpTextReferenceID, prefsPtr->basePICTResID, helpPanelTitle, &gHelpPanel);
- }
- HUnlock((Handle)prefsHandle);
- }
- else
- {
- err = kUnsupportedPrefsFormatErr;
- }
- }
- else
- {
- err = kNoPrefsErr;
- }
- return(err);
- }
-
-
- //--------------------------------------------------------------------------------
- // ShouldDrawColor
- //
- // IN: none
- // OUT: Boolean indicating true if we've got a color quickdraw
- // monitor with sufficient colors to display our color picts
- //
- //--------------------------------------------------------------------------------
-
- static Boolean ShouldDrawColor(void)
- {
- SInt32 info;
- return Gestalt(gestaltQuickdrawVersion, &info) == noErr && info >= gestalt8BitQD && (*(*GetMainDevice())->gdPMap)->pixelSize >= 8;
- }
-
-
- //--------------------------------------------------------------------------------
- // SendQuitEventToApplication
- //
- // Function that Quits gApplicationPSN
- //
- //--------------------------------------------------------------------------------
-
- void SendQuitEventToApplication()
- {
- OSErr theErr = noErr;
- AppleEvent theResultEvent;
-
-
- // Create target desc.
- AEDesc theTargetApp;
- theErr = AECreateDesc(typeProcessSerialNumber, &gApplicationPSN, sizeof(gApplicationPSN), &theTargetApp);
-
- // Bring them to the front in case they put up a modal dialog on quit (i.e. Save dialog).
- SetFrontProcess(&gApplicationPSN);
-
- // Create event
- if (theErr == noErr)
- {
- theErr = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &theTargetApp, 0, 0, &theResultEvent);
- AEDisposeDesc(&theTargetApp);
- }
-
- // Send it
- if (theErr == noErr)
- {
- AppleEvent theReply;
- theReply.descriptorType = 'NULL';
- theReply.dataHandle = NULL;
-
- theErr = AESend(&theResultEvent, &theReply, kAENoReply, kAENormalPriority, 200, NULL, NULL);
-
- AEDisposeDesc(&theReply);
- AEDisposeDesc(&theResultEvent);
- }
- }
-
-
- //--------------------------------------------------------------------------------
- // SetUpAppleEventHandlers
- //--------------------------------------------------------------------------------
-
- ShellErr SetUpAppleEventHandlers()
- {
- ShellErr err = noErr;
- gChildDiedHandlerUPP = NewAEEventHandlerProc(ChildDiedHandler);
-
- // Any application
- err = AEInstallEventHandler(kCoreEventClass, kAEApplicationDied, gChildDiedHandlerUPP, kAEApplicationDied, false);
- if (err != noErr)
- err = kInternalErr;
-
- return(err);
- }
-
-
- //--------------------------------------------------------------------------------
- // RemoveAppleEventHandlers
- //--------------------------------------------------------------------------------
-
- ShellErr RemoveAppleEventHandlers()
- {
- ShellErr err = noErr;
-
- err = AERemoveEventHandler(kCoreEventClass, kAEApplicationDied, gChildDiedHandlerUPP, false);
- if (err != noErr)
- err = kInternalErr;
- else
- DisposeRoutineDescriptor(gChildDiedHandlerUPP);
-
- return(err);
- }
-
-
- //--------------------------------------------------------------------------------
- // ChildDiedHandler
- //--------------------------------------------------------------------------------
-
- pascal OSErr ChildDiedHandler(const AppleEvent *inAppleEvent, const AppleEvent */* outReply */, SInt32 /* inRefcon */ )
- {
- SInt32 theActualSize;
- DescType returnedType;
- ProcessSerialNumber thelQuitApplicationPSN;
-
- EnterPlugin();
-
- AEGetParamPtr(inAppleEvent, keyProcessSerialNumber, typeProcessSerialNumber, &returnedType, &thelQuitApplicationPSN, sizeof(gApplicationPSN), &theActualSize);
-
- // Check to make sure that the application that quit is the application that was launched
- if ((thelQuitApplicationPSN.highLongOfPSN == gApplicationPSN.highLongOfPSN) && (thelQuitApplicationPSN.lowLongOfPSN == gApplicationPSN.lowLongOfPSN))
- {
- gApplicationLaunched = false;
- PSGoToNextPlugin(kUseDefaultNextModuleName);
- }
-
- ExitPlugin();
-
- return noErr;
- }
-